<!-- directive:title HTML5拖放API对嵌套列表进行排序 -->
<!-- directive:breadcrumb 角拖和下拉列表 -->
<div class='panel-body'>
    <pre>
        ██████  ██████   ███    ██ ███████ ████████ ██████  ██    ██  ██████ ████████  ██████  ██████
        ██      ██    ██ ████   ██ ██         ██    ██   ██ ██    ██ ██         ██    ██    ██ ██   ██
        ██      ██    ██ ██ ██  ██ ███████    ██    ██████  ██    ██ ██         ██    ██    ██ ██████
        ██      ██    ██ ██  ██ ██      ██    ██    ██   ██ ██    ██ ██         ██    ██    ██ ██   ██
        ██████  ██████   ██   ████ ███████    ██    ██   ██  ██████   ██████    ██     ██████  ██   ██
    </pre>
    <div class='panel panel-default'>
        <div class='panel-heading'> 角拖和下拉列表 </div>
        <div class='panel-body'>
            <article class="docs-content">
                <p class="text-success">两边样式需要不同 --没问题 拖拽列表和拖拽项都是分开声明的</p>
                <p class="text-success">左边不能排序 右边可以排序 --没问题 设置拖拽列表的接受项参数</p>
                <p class="text-success">左边可以拖动到右边 单一或多个 --没问题 事件控制本次拖拽后是否禁用</p>
                <p class="text-success">右边不能拖动到左边 --没问题 设置拖拽列表的接受项参数</p>
                <p class="text-success">右边可以被外部删掉 --没问题 绑定的数据均可以进行操作</p>
                <p class="text-danger">===</p>
            </article>
            <div class="row">
                <div class="col-sm-6 simpleDemo1">
                    <ul dnd-list="models.lists.A"
                        dnd-effect-allowed="copymove"
                        dnd-allowed-types="['noone']">
                        <li ng-repeat="item in models.lists.A"
                            dnd-draggable="item"
                            dnd-type="'onlya'"
                            dnd-copied="dnd.Acopied(item)"
                            dnd-moved="dnd.Acopied(item)"
                            dnd-disable-if="item.disabled"
                            dnd-selected="models.selected = item"
                            ng-class="{'selected': models.selected === item}">
                            {{ item.label + (item.disabled?"禁用":"") }}
                        </li>
                    </ul>
                </div>
                <div class="col-sm-6 simpleDemo2">
                    <ul dnd-list="models.lists.B"
                        dnd-effect-allowed="move"
                        dnd-allowed-types="['onlya']">
                        <li ng-repeat="item in models.lists.B"
                            dnd-draggable="item"
                            dnd-type="'onlya'"
                            dnd-moved="models.lists.B.splice($index, 1)"
                            dnd-selected="models.selected = item"
                            ng-class="{'selected': models.selected === item}">
                            {{item.label}}
                        </li>
                    </ul>
                </div>
            </div>
            <button type="button" class="btn btn-danger" ng-click="dnd.reset()">把"Item A1单拖" 放在B中第一项 测试删掉B中的"Item A1单拖" 复原A</button>
            <h3>models = {{models}}</h3>
            <uib-alert type="danger">
                不支持触摸设备，因为它们不实现HTML5拖放标准。但是，您也可以使用 shim 使其在触摸设备上工作。
            </uib-alert>
            <article class="docs-content">
                <h2> 支持的浏览器</h2>
                <p><strong>不支持触摸设备</strong>，因为它们不实现HTML5拖放标准。但是，您也可以使用<a href="https://github.com/timruffles/ios-html5-drag-drop-shim">垫片</a>使其在触摸设备上工作。</p>
                <p><em>不支持</em> Internet Explorer 8或更低版本，但所有现代浏览器都是（请参阅changelog以获取经过测试的浏览器列表）。</p>
                <h2> 下载和安装</h2>
                <ul>
                    <li>下载<code>angular-drag-and-drop-lists.js</code>（或缩小版本）并将其包含在您的应用程序中。如果您使用bower或npm，只需包含该<code>angular-drag-and-drop-lists</code>包。</li>
                    <li>将<code>dndLists</code>模块添加为角度应用程序的依赖项。</li>
                </ul>
                <h2> dnd-draggable指令</h2>
                <p>使用dnd-draggable指令使元素可拖动</p>
                <p><strong>属性</strong></p>
                <ul>
                    <li><code>dnd-draggable</code>必需属性。该值必须是表示元素数据的对象。在拖放操作的情况下，对象将在接收端被序列化和反序列化。</li>
                    <li><code>dnd-effect-allowed</code>使用此属性可限制可执行的操作。有效选项是<code>move</code>，<code>copy</code>和<code>link</code>，以及<code>all</code>，<code>copyMove</code>，<code>copyLink</code>和<code>linkMove</code>，而<code>move</code>为默认值。这些操作的语义由您决定，必须使用下面描述的回调来实现。如果您允许多个选项，则用户可以使用修改键（特定于操作系统）在它们之间进行选择。光标将相应地更改，期望IE和Edge，这是不支持的。请注意，此属性的实现在IE9中非常错误。此属性与<code>dnd-external-sources</code>Safari和IE
                        一起使用，在浏览器选项卡中拖动时限制将丢失。<a href="https://github.com/marceljuenemann/angular-drag-and-drop-lists/wiki/Drop-Effects-Design">设计文档</a> </li>
                    <li><code>dnd-type</code>如果应用程序中有不同类型的项目，并且您希望限制哪些项目可以放入哪些列表，请使用此属性。与dnd-list上的dnd-allowed-types组合。此属性必须是小写字符串。可以使用大写字符，但会自动转换为小写字母。</li>
                    <li><code>dnd-disable-if</code>您可以使用此属性动态禁用元素的可拖动性。如果您有某些列表项不希望是可拖动的，或者如果您想要完全禁用拖放而没有两个不同的代码分支（例如，只允许管理员），这将非常有用。</li>
                </ul>
                <p><strong>回调</strong></p>
                <ul>
                    <li><code>dnd-dragstart</code>拖动元素时调用的回调。原始的dragstart事件将在局部<code>event</code>变量中提供。</li>
                    <li><code>dnd-moved</code>移动元素时调用的回调。通常，您将从此回调中的原始列表中删除元素，因为该指令不会自动为您执行此操作。原始dragend事件将在local <code>event</code>变量中提供。</li>
                    <li><code>dnd-copied</code>与dnd-moved相同，只是在复制元素而不是移动元素时调用它。原始dragend事件将在local <code>event</code>变量中提供。</li>
                    <li><code>dnd-linked</code>与dnd-moved相同，只是在链接元素而不是移动元素时调用它。原始dragend事件将在local <code>event</code>变量中提供。</li>
                    <li><code>dnd-canceled</code>如果拖动元素，则调用的回调，但操作已取消且元素未被删除。原始dragend事件将在本地事件变量中提供。</li>
                    <li><code>dnd-dragend</code>拖动操作结束时调用的回调。可用的局部变量是<code>event</code>和<code>dropEffect</code>。</li>
                    <li><code>dnd-selected</code>单击元素但未拖动时调用的回调。原始点击事件将在局部<code>event</code>变量中提供。</li>
                    <li><code>dnd-callback</code>传递给dropzone回调的自定义回调，可用于在源和目标作用域之间进行通信。dropzone可以将用户定义的变量传递给此回调。这可以用于传输没有序列化的对象，请参阅。</li>
                </ul>
                <p><strong>CSS类</strong></p>
                <ul>
                    <li><code>dndDragging</code>在拖动元素时，此类将添加到元素中。它会影响拖动时看到的元素和停留在其位置的源元素。不要尝试使用此类隐藏源元素，因为这将中止拖动操作。</li>
                    <li><code>dndDraggingSource</code> 在拖动操作开始后，此类将添加到元素中，这意味着它仅影响仍在其源位置的原始元素，而不影响用户使用鼠标指针拖动的“元素”</li>
                </ul>
                <h2> dnd-list指令</h2>
                <p>使用dnd-list属性使list元素成为dropzone。通常，您将使用ng-repeat指令将单个li元素添加为子元素。如果你不这样做，我们将无法正确定位掉落的元素。如果希望列表可以排序，也可以将dnd-draggable指令添加到li元素中。</p>
                <p><strong>属性</strong></p>
                <ul>
                    <li><code>dnd-list</code>必需属性。该值必须是应插入已删除元素的数据的数组。如果与自己处理插入的自定义dnd-drop处理程序一起使用，则该值可以为空。</li>
                    <li><code>dnd-allowed-types</code>可选项目类型的可选数组。使用时，只有具有匹配的dnd-type属性的项才可以删除。大写字符将自动转换为小写字母。</li>
                    <li><code>dnd-effect-allowed</code>可选字符串表达式，用于限制可对列表执行的放置效果。有关允许选项的更多详细信息，请参阅dnd-draggable上的dnd-effect-allowed。默认值为<code>all</code>。</li>
                    <li><code>dnd-disable-if</code>可选的布尔表达式。当它的计算结果为true时，不会进入列表。请注意，这也会禁用重新排列列表中的项目。</li>
                    <li><code>dnd-horizontal-list</code>可选的布尔表达式。当它的计算结果为true时，定位算法将使用列表项的左半部分和右半部分而不是上半部分和下半部分。</li>
                    <li><code>dnd-external-sources</code>可选的布尔表达式。当评估为true时，列表接受来自当前浏览器选项卡之外的源的删除，这允许在不同的浏览器选项卡上拖放。目前无法使用的唯一主要浏览器是Microsoft Edge。</li>
                </ul>
                <p><strong>回调</strong></p>
                <ul>
                    <li><code>dnd-dragover</code>在列表上拖动元素时调用的可选表达式。<b>如果设置了表达式，但未返回true，则不允许删除该元素。</b>将提供以下变量：
                        <ul>
                            <li><code>event</code> 浏览器发送的原始dragover事件。</li>
                            <li><code>index</code> 列表中将删除元素的位置。</li>
                            <li><code>type</code>在<code>dnd-type</code>对DND-拖动，或者不确定的，如果取消设置集。对于IE和Edge中的外部源的丢弃，将为null，因为我们在这些情况下不知道类型。</li>
                            <li><code>external</code>元素是否是从外部源拖动的。见<code>dnd-external-sources</code>。</li>
                            <li><code>dropEffect</code> 将要执行的dropEffect，请参阅dnd-effect-allowed。</li>
                            <li><code>callback</code>如果在源元素上设置了dnd-callback，则这是对回调的函数引用。可以使用以下自定义变量调用回调：<code>callback({var1: value1, var2: value2})</code>。回调将在源元素的范围内执行。如果设置了dnd-external-sources且external为true，则此回调将不可用。</li>

                        </ul>
                    </li>
                    <li><code>dnd-drop</code>在列表中删除元素时调用的可选表达式。可以使用与dnd-dragover相同的变量，但类型始终是已知的，因此永远不会为null。还会有一个<code>item</code>变量，即传输的对象。返回值决定了drop的进一步处理：
                        <ul>
                            <li><code>falsy</code> 下拉将被取消，元素将不会被插入。</li>
                            <li><code>true</code> 发出允许丢弃的信号，但是dnd-drop回调将负责插入元素。</li>
                            <li>否则：所有其他返回值将被视为要插入数组的对象。在大多数情况下，您只想返回<code>item</code>参数，但对可返回的内容没有限制。</li>
                        </ul>
                    </li>
                    <li><code>dnd-inserted</code>如果元素实际插入列表中，则在删除后调用的可选表达式。将提供与此相同的局部变量<code>dnd-drop</code>。请注意，对于同一列表中的重新排序，由于<code>dnd-moved</code>尚未调用的事实，旧元素仍将在列表中。</li>
                </ul>
                <p><strong>CSS类</strong></p>
                <ul>
                    <li><code>dndPlaceholder</code>在列表上拖动元素时，将添加新的占位符子元素。此元素属于类型<code>li</code>且具有类<code>dndPlaceholder</code>集。或者，您可以通过使用<code>dndPlaceholder</code>类创建子元素来定义自己的占位符。</li>
                    <li><code>dndDragover</code> 当一个元素被拖过列表时，该类将被添加到列表中。</li>
                </ul>
                <h2> dnd-nodrag指令</h2>
                <p>使用元素<code>dnd-nodrag</code>内部的属性<code>dnd-draggable</code>来阻止它们开始拖动操作。如果要在元素内部使用输入<code>dnd-draggable</code>元素或创建特定的句柄元素，这尤其有用。</p>
                <p><strong>注意：</strong>此指令在Internet Explorer 9中不起作用。</p>
                <p></p>
                <h2> dnd-handle指令</h2>
                <p><code>dnd-handle</code>在<code>dnd-nodrag</code>元素中使用该指令，以便允许拖动该元素。因此，通过组合<code>dnd-nodrag</code>，<code>dnd-handle</code>您可以允许<code>dnd-draggable</code>仅通过特定<em>句柄</em>元素拖动元素。</p>
                <p><strong>注意：</strong> Internet Explorer将把handle元素显示为拖动图像而不是<code>dnd-draggable</code>元素。您可以通过在拖动时不同地设置控制元素的样式来解决此问题。使用CSS选择器<code>.dndDragging:not(.dndDraggingSource) [dnd-handle]</code>。</p>
                <p></p>
                <h2> 推荐的CSS样式</h2>
                <p>建议您应用以下CSS样式：</p>
                <ul>
                    <li>如果您的应用程序是通过拖放移动元素，建议您在拖动时隐藏源元素，即<code>display: none</code>在<code>.dndDraggingSource</code>类上设置。</li>
                    <li>如果您的应用程序允许将元素拖放到空列表中，则需要确保空列表的高度或宽度不会为零，例如通过设置a <code>min-width</code>。</li>
                    <li>您应该相应地设置<code>.dndPlaceholder</code>类的样式。</li>
                </ul>
                <p><strong>注意：</strong><code>postion: relative</code>某些元素需要此指令的早期版本，但不再需要。</p>
            </article>
        </div>
    </div>
    <style media="screen" ui-bs>
        .simpleDemo1 ul[dnd-list],
        .simpleDemo1 ul[dnd-list] > li { position: relative; }
        .simpleDemo1 ul[dnd-list] { min-height: 42px; padding-left: 0px;display: flex; }
        .simpleDemo1 ul[dnd-list] .dndDraggingSource { display: none; }
        .simpleDemo1 ul[dnd-list] .dndPlaceholder { display: block; background-color: #ddd; min-height: 42px; }
        .simpleDemo1 ul[dnd-list] li { background-color: #fff; border: 1px solid #ddd; border-top-right-radius: 4px; border-top-left-radius: 4px; display: block; padding: 10px 15px; margin: 10px; }
        .simpleDemo1 ul[dnd-list] li.selected { background-color: #dff0d8; color: #3c763d; }
        .simpleDemo2 ul[dnd-list],
        .simpleDemo2 ul[dnd-list] > li { position: relative; }
        .simpleDemo2 ul[dnd-list] { min-height: 42px; padding-left: 0px; }
        .simpleDemo2 ul[dnd-list] .dndDraggingSource { display: none; }
        .simpleDemo2 ul[dnd-list] .dndPlaceholder { display: block; background-color: #ddd; min-height: 42px; }
        .simpleDemo2 ul[dnd-list] li { background-color: #fff; border: 1px solid #ddd; border-top-right-radius: 4px; border-top-left-radius: 4px; display: block; padding: 10px 15px; float: left; padding: 10px 15px; margin: 10px; }
        .simpleDemo2 ul[dnd-list] li.selected { background-color: #dff0d8; color: #3c763d; }
    </style>
</div>
